use anyhow::Result;
use dialoguer::{Confirm, Input, Password, Select};

pub enum ParamType {
    String,
    Inetger,
    Password,
    Select,
    Confirm,
}
#[derive(Debug)]
pub enum CliValue {
    Int(usize),
    String(String),
    Bool(bool)
}

impl CliValue {
    pub fn as_int(&self) -> Option<usize> {
        match self {
            CliValue::Int(i) => Some(*i),
            _ => None,
        }
    }

    pub fn as_string(&self) -> Option<String> {
        match self {
            CliValue::String(s) => Some(s.to_string()),
            _ => None,
        }
    }

    pub fn as_bool(&self) -> Option<bool> {
        match self {
            CliValue::Bool(b) => Some(*b),
            _ => None,
        }
    }
}
pub fn run_cli(name: String, param_type: ParamType, items: Option<Vec<String>>, default_value: Option<String>, allow_empty: bool) -> Result<CliValue> {
    match param_type {
        ParamType::Inetger => {
            let mut input = Input::new().with_prompt(name);
            if let Some(d) = default_value {
                input = input.default(d.parse::<i64>()?);
            }
            let value = input.allow_empty(allow_empty).interact()?;
            Ok(CliValue::Int(value as usize))
        }
        ParamType::String => {
            let mut input = Input::new().with_prompt(name);
            if let Some(d) = default_value {
                input = input.default(d);
            }
            Ok(CliValue::String(input.allow_empty(allow_empty).interact_text()?))
        }
        ParamType::Select => {
            let mut input = Select::new().with_prompt(name).items(items.as_ref().expect("Select 参数错误！"));
            if let Some(d) = default_value {
                input = input.default(d.parse::<usize>()?);
            }
            Ok(CliValue::Int(input.interact()?))
        }
        ParamType::Password => {
            Ok(CliValue::String(Password::new().with_prompt(name).allow_empty_password(allow_empty).interact()?))
        }
        ParamType::Confirm => {
            Ok(CliValue::Bool(Confirm::new().with_prompt(name).interact()?))
        }
    }
}